/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_Vk帧缓存.h"
#include "../Core/结构from成员.h"
#include "../buffer/Vk图像.h"

#include "底层绘图/底层绘图框架.h"
#include "纹理/纹理.h"




void f_frame_构建交换链缓存(S_Vk帧缓存& frame, bool 多重采样) {
	
	vector<VkImageView> 颜色纹理 = f_取_S_VkImage_纹理视图(frame.m_交换面颜色缓存);
	vector<VkImageView> 深度纹理 = f_取_S_VkImage_纹理视图(frame.m_交换面深度缓存);

	uint32 num = 深度纹理.size();
	uint32 附件数量 = 0;

	VkImageView 图像视图附件[4] = { 颜色纹理[0], 0, 0, 0 };
	
	VkFramebufferCreateInfo 帧缓存创建信息 = {};
	帧缓存创建信息.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	帧缓存创建信息.renderPass = frame.m_渲染通道;
	帧缓存创建信息.pAttachments = 图像视图附件;
	帧缓存创建信息.width = frame.m_Size.x;
	帧缓存创建信息.height = frame.m_Size.y;
	帧缓存创建信息.layers = 1;

	frame.m_开始渲染信息.renderArea.extent.width = frame.m_Size.x;
	frame.m_开始渲染信息.renderArea.extent.height = frame.m_Size.y;

	if (多重采样) {
		帧缓存创建信息.attachmentCount = 3;
		图像视图附件[1] = 颜色纹理[1];
		图像视图附件[2] = 深度纹理[0];

	}
	else {
		帧缓存创建信息.attachmentCount = 2;
		图像视图附件[1] = 深度纹理[0];
	}

	frame.m_帧缓存.resize(1);
	if (vkCreateFramebuffer(frame.m_设备, &帧缓存创建信息, NULL, &frame.m_帧缓存[0]) != VK_SUCCESS) {
		throw std::runtime_error("创建帧缓存失败!");
	}
}



S_Vk帧缓存::S_Vk帧缓存(const uvec2 size) :S_帧缓存(size) {
	//m_帧缓存;
	m_颜色图像 = nullptr;

	m_全屏数量 = 3;

	m_背景清除值[0].color.float32[0] = 0.1f;
	m_背景清除值[0].color.float32[1] = 0.1f;
	m_背景清除值[0].color.float32[2] = 0.1f;
	m_背景清除值[0].color.float32[3] = 1.0f;
	
	m_背景清除值[1].color.float32[0] = 0.1f;
	m_背景清除值[1].color.float32[1] = 0.1f;
	m_背景清除值[1].color.float32[2] = 0.1f;
	m_背景清除值[1].color.float32[3] = 1.0f;
	
	//m_背景清除值[1].depthStencil.depth = 1.0;
	//m_背景清除值[1].depthStencil.stencil = 0;

	m_背景清除值[2].depthStencil.depth = 1.0;
	m_背景清除值[2].depthStencil.stencil = 0;


	m_开始渲染信息 = {};
	m_开始渲染信息.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
	m_开始渲染信息.clearValueCount = 3;
	m_开始渲染信息.framebuffer = 0;
	m_开始渲染信息.pClearValues = m_背景清除值;
	m_开始渲染信息.renderArea.offset.x = 0;
	m_开始渲染信息.renderArea.offset.y = 0;

}

void S_Vk帧缓存::f_构建交换链缓存(VkDevice& dev, bool 深度, uint8 多重采样) {
	m_设备 = dev;

	vector<VkImageView> 颜色纹理 = f_取_S_VkImage_纹理视图(m_交换面颜色缓存);
	vector<VkImageView> 深度纹理 = f_取_S_VkImage_纹理视图(m_交换面深度缓存);

	uint32 num = 2;
	深度 = 深度纹理.size() ? true : false;
	//uint32 i = 0;
	VkFramebufferCreateInfo 帧缓存创建信息 = {};
	帧缓存创建信息.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	帧缓存创建信息.renderPass = m_渲染通道;
	帧缓存创建信息.width = m_Size.x;
	帧缓存创建信息.height = m_Size.y;
	帧缓存创建信息.layers = 1;


	VkImageView 图像视图附件[4] = { 颜色纹理[0], 0, 0, 0 };
	帧缓存创建信息.pAttachments = 图像视图附件;
	帧缓存创建信息.attachmentCount = m_颜色通道数量;

	m_帧缓存.resize(num);

	if (多重采样) {
		
		if (深度) {
			for (uint32 i = 0; i < num; ++i) {
				图像视图附件[1] = 颜色纹理[i + 1];
				图像视图附件[2] = 深度纹理[0];
				if (vkCreateFramebuffer(dev, &帧缓存创建信息, NULL, &m_帧缓存[i]) != VK_SUCCESS) {
					throw std::runtime_error("创建帧缓存失败!");
				}
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				图像视图附件[1] = 颜色纹理[i + 1];
				if (vkCreateFramebuffer(dev, &帧缓存创建信息, NULL, &m_帧缓存[i]) != VK_SUCCESS) {
					throw std::runtime_error("创建帧缓存失败!");
				}
			}
		}
		
	}
	else {
		if (深度) {
			for (uint32 i = 0; i < num; ++i) {
				图像视图附件[0] = 颜色纹理[i];
				图像视图附件[1] = 深度纹理[0];

				if (vkCreateFramebuffer(dev, &帧缓存创建信息, NULL, &m_帧缓存[i]) != VK_SUCCESS) {
					throw std::runtime_error("创建帧缓存失败!");
				}
			}
		}
		else {
			for (uint32 i = 0; i < num; ++i) {
				图像视图附件[0] = 颜色纹理[i];

				if (vkCreateFramebuffer(dev, &帧缓存创建信息, NULL, &m_帧缓存[i]) != VK_SUCCESS) {
					throw std::runtime_error("创建帧缓存失败!");
				}
			}
		}
	}
}

void S_Vk帧缓存::f_构建交换链缓存(S_设备环境& ctx, uint8 附件数量) {
	m_设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)(ctx.m_绘图环境));

	S_Vk帧缓存::f_构建交换链缓存(m_设备, m_渲染通道, 附件数量);
}

void S_Vk帧缓存::f_release(bool 销毁交互纹理) {
	if (销毁交互纹理) {
		uint32 num = m_交换面颜色缓存.size() - 1;
		for (uint32 i = 0; i < num; ++i) {
			if(m_交换面颜色缓存[i]) f_tex_销毁纹理(m_交换面颜色缓存[i]);
		}
	}
	
	for (auto& e : m_交换面深度缓存) {
		f_tex_销毁纹理(e);
	}

	for (auto& e : m_帧缓存) vkDestroyFramebuffer(m_设备, e, 0);

	m_交换面颜色缓存.clear();
	m_交换面深度缓存.clear();
	m_帧缓存.clear();
	
}

void S_Vk帧缓存::f_reSize(uvec2 size) {
	for (auto& e : m_帧缓存) vkDestroyFramebuffer(m_设备, e, 0);
	m_帧缓存.clear();

}

void S_Vk帧缓存::f_构建阴影帧缓存(VkDevice& dev, const VkRenderPass& rp) {
	m_设备 = dev;

	vector<VkImageView> 深度纹理 = f_取_S_VkImage_纹理视图(m_交换面深度缓存);
	
	VkFramebufferCreateInfo 帧缓存创建信息 = {};
	帧缓存创建信息.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	帧缓存创建信息.renderPass = rp;
	帧缓存创建信息.attachmentCount = 1;
	帧缓存创建信息.pAttachments = &深度纹理[0];
	帧缓存创建信息.width = m_Size.x;
	帧缓存创建信息.height = m_Size.y;
	帧缓存创建信息.layers = 1;

	m_帧缓存.resize(1);
	if (vkCreateFramebuffer(dev, &帧缓存创建信息, NULL, &m_帧缓存[0]) != VK_SUCCESS) {
		throw std::runtime_error("创建帧缓存失败!");
	}
}

void f_frameBuf_set采样(S_设备环境& ctx, S_帧缓存* 帧缓存, E_纹理格式 纹理格式) {
	S_Vk帧缓存& fb = *dynamic_cast<S_Vk帧缓存*>(帧缓存);

	if (fb.m_颜色图像) {
		f_tex_销毁纹理(fb.m_颜色图像);
	}
	fb.m_颜色图像 = f_tex_创建帧缓存纹理(ctx, _uVec3(帧缓存->m_Size, 1), 纹理格式, E_纹理维度类型::e_2D, ctx.m_采样数);
}


static void f_fb_创建阴影渲染帧(S_Vk帧缓存* fb, uvec2 faceSize, S_VkImage* depth) {

	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass = fb->m_渲染通道;
	// 一个颜色附件和一个深度附件
	framebufferInfo.attachmentCount = 1;

	framebufferInfo.width = faceSize.x;
	framebufferInfo.height = faceSize.y;
	// 帧缓存的层数
	framebufferInfo.layers = 1;

	fb->m_帧缓存.resize(1);
	framebufferInfo.pAttachments = &(depth->m_View);
	vkCreateFramebuffer(fb->m_设备, &framebufferInfo, nullptr, &(fb->m_帧缓存[0]));

	fb->m_Size = faceSize;
}

S_帧缓存* f_fb_创建阴影帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理* 深度纹理) {
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)ctx.m_绘图环境;
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);

	S_Vk帧缓存* fb = new S_Vk帧缓存(faceSize);
	fb->m_渲染通道 = 绘图设备配置->m_阴影渲染通道;
	fb->m_设备 = 逻辑设备;

	uvec3 area = { faceSize.x, faceSize.y, 1 };
	fb->m_交换面深度缓存.push_back(dynamic_cast<S_VkImage*>(深度纹理));

	f_fb_创建阴影渲染帧(fb, faceSize, fb->m_交换面深度缓存[0]);
	return fb;
}

void f_fb_重置阴影帧缓存(S_帧缓存* fb, uvec2 faceSize) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);

	for (auto& e : 帧缓存->m_帧缓存) vkDestroyFramebuffer(帧缓存->m_设备, e, 0);
	帧缓存->m_帧缓存.clear();

	f_fb_创建阴影渲染帧(帧缓存, faceSize, 帧缓存->m_交换面深度缓存[0]);
}





static void f_fb_创建环境渲染帧(S_Vk帧缓存* fb, uvec2 faceSize, S_VkImage* color, S_VkImage* depth) {

	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass = fb->m_渲染通道;
	// 一个颜色附件和一个深度附件
	framebufferInfo.attachmentCount = 2;

	framebufferInfo.width = faceSize.x;
	framebufferInfo.height = faceSize.y;
	// 帧缓存的层数
	framebufferInfo.layers = 1; 

	fb->m_帧缓存.resize(6);
	for (uint32 i = 0; i < 6; ++i) {
		VkImageView 图像视图附件[2];

		图像视图附件[0] = (color)->m_CubeView[i];
		图像视图附件[1] = (depth)->m_CubeView[i];

		framebufferInfo.pAttachments = 图像视图附件;
		vkCreateFramebuffer(fb->m_设备, &framebufferInfo, nullptr, &fb->m_帧缓存[i]);
	}

	fb->m_Size = faceSize;
}

S_帧缓存* f_fb_创建立方体帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理* color, S_纹理* depth) {
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)ctx.m_绘图环境);

	S_Vk帧缓存* fb = new S_Vk帧缓存(faceSize);
	fb->m_设备 = (VkDevice)ctx.m_逻辑设备.设备;

	fb->m_渲染通道 = 绘图设备配置.m_环境渲染通道;

	fb->m_交换面颜色缓存.push_back(dynamic_cast<S_VkImage*>(color));
	fb->m_交换面深度缓存.push_back(dynamic_cast<S_VkImage*>(depth));

	f_fb_创建环境渲染帧(fb, faceSize, fb->m_交换面颜色缓存[0], fb->m_交换面深度缓存[0]);

	return fb;
}

void f_fb_重置立方体帧缓存(S_帧缓存* fb, uvec2 faceSize) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);

	for (auto& e : 帧缓存->m_帧缓存) vkDestroyFramebuffer(帧缓存->m_设备, e, 0);
	帧缓存->m_帧缓存.clear();

	f_fb_创建环境渲染帧(帧缓存, faceSize, 帧缓存->m_交换面颜色缓存[0], 帧缓存->m_交换面深度缓存[0]);
}




static void f_fb_创建合成渲染帧(S_Vk帧缓存* fb, uvec2 faceSize) {

	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass = fb->m_渲染通道;
	// 一个颜色附件和一个深度附件
	

	framebufferInfo.width = faceSize.x;
	framebufferInfo.height = faceSize.y;
	// 帧缓存的层数
	framebufferInfo.layers = 1;

	fb->m_帧缓存.resize(1);
	VkImageView 图像视图附件[3];

	图像视图附件[0] = ((S_VkImage*)fb->m_颜色图像)->m_View;
	图像视图附件[1] = ((S_VkImage*)fb->m_深度图像)->m_View;
	图像视图附件[2] = fb->m_交换面颜色缓存[0]->m_View;
	

	framebufferInfo.pAttachments = 图像视图附件;
	framebufferInfo.attachmentCount = 3;

	vkCreateFramebuffer(fb->m_设备, &framebufferInfo, nullptr, &fb->m_帧缓存[0]);
	fb->m_Size = faceSize;
}

S_帧缓存* f_fb_创建合成帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理* color, E_MS次数 采样次数) {
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)ctx.m_绘图环境);

	S_Vk帧缓存* 帧缓存 = new S_Vk帧缓存(faceSize);
	帧缓存->m_设备 = (VkDevice)ctx.m_逻辑设备.设备;

	帧缓存->m_颜色图像 = f_tex_创建帧缓存纹理(ctx, { faceSize.x, faceSize.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D, 采样次数);
	f_tex_安装纹理采样器(帧缓存->m_颜色图像, S_全局缓存::g_默认采样器);

	帧缓存->m_深度图像 = f_tex_创建深度纹理(ctx, { faceSize.x, faceSize.y, 1 }, 采样次数, E_纹理维度类型::e_2D);
	f_tex_安装纹理采样器(帧缓存->m_颜色图像, S_全局缓存::g_默认采样器);


	帧缓存->m_渲染通道 = f_fb_创建合成渲染通道(帧缓存->m_设备, f_vk_getVK图像格式(E_纹理格式::e_tf_RGBA8U_归一化), f_vk_getVK图像格式(E_纹理格式::e_tf_D32F), 采样次数);
	帧缓存->m_交换面颜色缓存.push_back(dynamic_cast<S_VkImage*>(color));

	f_fb_创建合成渲染帧(帧缓存, faceSize);
	return 帧缓存;
}

void f_fb_重置合成帧缓存(S_帧缓存* fb, uvec2 faceSize) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);

	for (auto& e : 帧缓存->m_帧缓存) vkDestroyFramebuffer(帧缓存->m_设备, e, 0);
	帧缓存->m_帧缓存.clear();

	f_fb_创建合成渲染帧(帧缓存, faceSize);
}





static void f_fb_创建几何缓存渲染帧(S_Vk帧缓存* fb, uvec2 faceSize, uint32 附件数量, S_VkImage** color, S_VkImage* depth) {

	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass = fb->m_渲染通道;
	// 一个颜色附件和一个深度附件

	framebufferInfo.width = faceSize.x;
	framebufferInfo.height = faceSize.y;
	// 帧缓存的层数
	framebufferInfo.layers = 1;

	fb->m_帧缓存.resize(1);
	std::vector<VkImageView> 图像视图附件(附件数量);

	for (uint32 i = 0; i < 附件数量; ++i) {
		图像视图附件[i] = (color[i]->m_View);
	}
	图像视图附件.push_back(depth->m_View);

	framebufferInfo.pAttachments = 图像视图附件.data();
	framebufferInfo.attachmentCount = 附件数量 + 1;

	vkCreateFramebuffer(fb->m_设备, &framebufferInfo, nullptr, &fb->m_帧缓存[0]);

	fb->m_Size = faceSize;
}

S_帧缓存* f_fb_创建几何缓存帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理** color, S_纹理* depth, uint32 纹理数量) {
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)ctx.m_绘图环境);

	S_Vk帧缓存* 帧缓存 = new S_Vk帧缓存(faceSize);
	帧缓存->m_设备 = (VkDevice)ctx.m_逻辑设备.设备;
	
	帧缓存->m_渲染通道 = 绘图设备配置.m_几何缓存渲染通道;
	
	for (uint32 i = 0; i < 纹理数量; ++i) {
		auto* attachment = dynamic_cast<S_VkImage*>(color[i]);
		帧缓存->m_交换面颜色缓存.push_back(attachment);
	}
	帧缓存->m_交换面深度缓存.push_back(dynamic_cast<S_VkImage*>(depth));
	
	f_fb_创建几何缓存渲染帧(帧缓存, faceSize, 纹理数量, 帧缓存->m_交换面颜色缓存.data(), 帧缓存->m_交换面深度缓存[0]);
	return 帧缓存;
}

void f_fb_重置几何缓存帧缓存(S_帧缓存* fb, uvec2 faceSize) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);

	for (auto& e : 帧缓存->m_帧缓存) vkDestroyFramebuffer(帧缓存->m_设备, e, 0);
	帧缓存->m_帧缓存.clear();

	uint32 纹理数量 = 帧缓存->m_交换面颜色缓存.size();
	f_fb_创建几何缓存渲染帧(帧缓存, faceSize, 纹理数量, 帧缓存->m_交换面颜色缓存.data(), 帧缓存->m_交换面深度缓存[0]);
}





static void f_fb_创建UI帧缓存对象(S_Vk帧缓存* 帧缓存, uint32 帧ID, const uvec2& size, uint32 num, VkImageView 附件1[4]) {
	
	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass = 帧缓存->m_渲染通道;
	// 一个颜色附件和一个深度附件
	framebufferInfo.attachmentCount = num;
	framebufferInfo.pAttachments = 附件1;

	framebufferInfo.width = size.x;
	framebufferInfo.height = size.y;
	framebufferInfo.layers = 1; 

	vkCreateFramebuffer(帧缓存->m_设备, &framebufferInfo, nullptr, &帧缓存->m_帧缓存[帧ID]);

	帧缓存->m_开始渲染信息.renderArea.extent.width = size.x;
	帧缓存->m_开始渲染信息.renderArea.extent.height = size.y;
	帧缓存->m_开始渲染信息.renderPass = 帧缓存->m_渲染通道;
	//帧缓存->m_开始渲染信息.pClearValues;
	帧缓存->m_Size = size;
}

S_帧缓存* f_fb_创建UI渲染帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理* color[4]) {
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)ctx.m_绘图环境);

	S_Vk帧缓存* 帧缓存 = new S_Vk帧缓存(faceSize);
	帧缓存->m_设备 = (VkDevice)ctx.m_逻辑设备.设备;
	帧缓存->m_渲染通道 = 绘图设备配置.m_窗口UI渲染通道;

	帧缓存->m_帧缓存.resize(1);
	VkImageView 附件1[4] = { 
		dynamic_cast<S_VkImage*>(color[0])->m_View, 
		dynamic_cast<S_VkImage*>(color[1])->m_View,
		};
	f_fb_创建UI帧缓存对象(帧缓存, 0, faceSize, 2, 附件1 );
	
	return 帧缓存;
}

void f_fb_重置UI渲染帧缓存(S_设备环境& ctx, S_帧缓存* fb, const uvec2& faceSize, S_纹理* color[2]) {
	auto* dc = f_vk_get绘图环境(ctx);
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);
	vkDestroyFramebuffer(dc->m_设备, 帧缓存->m_帧缓存[0], 0);
	VkImageView 附件1[2] = { dynamic_cast<S_VkImage*>(color[0])->m_View, dynamic_cast<S_VkImage*>(color[1])->m_View };
	f_fb_创建UI帧缓存对象(帧缓存, 0, faceSize, 2, 附件1 );
}



S_帧缓存* f_fb_创建UI合成帧缓存(S_设备环境& ctx, uint32 num, const uvec2& faceSize, S_纹理* tex[4]) {
	S_VK渲染环境& 渲染环境 = *((S_VK渲染环境*)ctx.m_绘图环境);

	S_Vk帧缓存* 帧缓存 = new S_Vk帧缓存(faceSize);
	帧缓存->m_设备 = (VkDevice)ctx.m_逻辑设备.设备;
	帧缓存->m_渲染通道 = 渲染环境.m_窗口UI合成通道;

	帧缓存->m_帧缓存.resize(num);
	for (uint32 i = 0; i < num; ++i) {
		f_fb_创建UI帧缓存对象(帧缓存, i, faceSize, 1, &dynamic_cast<S_VkImage*>(tex[i])->m_View );
	}
	帧缓存->m_开始渲染信息.clearValueCount = 1;
	return 帧缓存;
}

void f_fb_重置UI合成帧缓存(S_设备环境& ctx, S_帧缓存* fb, const uvec2& faceSize, S_纹理* color[4]) {
	auto* dc = f_vk_get绘图环境(ctx);
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);
	for (auto& e : 帧缓存->m_帧缓存) {
		vkDestroyFramebuffer(dc->m_设备, e, 0);
	}
	
	for (uint32 i = 0; i < 帧缓存->m_帧缓存.size(); ++i) {
		f_fb_创建UI帧缓存对象(帧缓存, i, faceSize, 1, &dynamic_cast<S_VkImage*>(color[i])->m_View );
	}
}

void f_fb_销毁UI合成帧缓存(S_设备环境& ctx, S_帧缓存* fb) {
	auto* dc = f_vk_get绘图环境(ctx);
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);
	for (auto& e : 帧缓存->m_帧缓存) {
		vkDestroyFramebuffer(dc->m_设备, e, 0);
	}
}



static void f_创建帧缓存(S_Vk帧缓存* fb, const uvec2& faceSize, VkImageView 附件1[2]) {
	VkFramebufferCreateInfo framebufferInfo = {};
	framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
	framebufferInfo.renderPass		= fb->m_渲染通道;
	// 一个颜色附件和一个深度附件
	
	framebufferInfo.width			= faceSize.x;
	framebufferInfo.height			= faceSize.y;
	framebufferInfo.layers			= 1; 

	framebufferInfo.attachmentCount	= 2;
	framebufferInfo.pAttachments	= 附件1;

	vkCreateFramebuffer(fb->m_设备, &framebufferInfo, nullptr, &fb->m_帧缓存[0]);

	fb->m_开始渲染信息.renderArea.extent.width = faceSize.x;
	fb->m_开始渲染信息.renderArea.extent.height = faceSize.y;
	fb->m_Size = faceSize;
}

S_帧缓存* f_fb_创建3D场景帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理* color, S_纹理* depth) {
	auto rf = f_vk_get绘图环境(ctx);

	S_Vk帧缓存* 帧缓存 = new S_Vk帧缓存(faceSize);
	帧缓存->m_帧缓存.resize(1);
	帧缓存->m_设备		= (VkDevice)ctx.m_逻辑设备.设备;
	帧缓存->m_渲染通道	= rf->m_场景渲染通道;

	VkImageView 附件1[2] = { dynamic_cast<S_VkImage*>(color)->m_View, dynamic_cast<S_VkImage*>(depth)->m_View };
	f_创建帧缓存(帧缓存, faceSize, 附件1);
	
	return 帧缓存;
}

void f_fb_重置3D场景帧缓存(S_帧缓存* fb, const uvec2& faceSize, S_纹理* tex[]) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);
	vkDestroyFramebuffer(帧缓存->m_设备, 帧缓存->m_帧缓存[0], 0);

	VkImageView 附件1[2] = { dynamic_cast<S_VkImage*>(tex[0])->m_View, dynamic_cast<S_VkImage*>(tex[1])->m_View};
	f_创建帧缓存(帧缓存, faceSize, 附件1);
}


void f_fb_销毁帧缓存(S_帧缓存* fb) {
	S_Vk帧缓存* 帧缓存 = dynamic_cast<S_Vk帧缓存*>(fb);
	
	for (auto& e : 帧缓存->m_帧缓存) vkDestroyFramebuffer(帧缓存->m_设备, e, 0);

	帧缓存->m_交换面颜色缓存.clear();
	帧缓存->m_交换面深度缓存.clear();
	帧缓存->m_帧缓存.clear();
}




VkRenderPass f_fb_创建环境渲染通道(VkDevice 设备, E_纹理格式 颜色格式, E_纹理格式 深度格式) {

	VkAttachmentDescription attachmentColor = {};
	attachmentColor.format = f_vk_getVK图像格式(颜色格式);
	attachmentColor.samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentColor.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentColor.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentColor.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentColor.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentColor.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	attachmentColor.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

	VkAttachmentDescription attachmentDepth = {};
	attachmentDepth.format = f_vk_getVK图像格式(深度格式);
	attachmentDepth.samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentDepth.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
	attachmentDepth.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDepth.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentDepth.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDepth.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDepth.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
	


	VkAttachmentReference colorAttachmentRef = {};
	colorAttachmentRef.attachment = 0;
	colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	VkAttachmentReference depthAttachmentRef = {};
	depthAttachmentRef.attachment = 1;
	depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;


	VkSubpassDescription subpass = {};
	subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	subpass.colorAttachmentCount = 1;
	subpass.pColorAttachments = &colorAttachmentRef;
	subpass.pDepthStencilAttachment = &depthAttachmentRef;


	VkSubpassDependency dependency = {};
	dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
	dependency.dstSubpass = 0;
	dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
	dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
	dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
	dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;


	VkAttachmentDescription Attachment[2] = { attachmentColor, attachmentDepth };

	VkRenderPassCreateInfo renderPassInfo = {};
	renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	renderPassInfo.attachmentCount = 2;
	renderPassInfo.pAttachments = Attachment;
	renderPassInfo.subpassCount = 1;
	renderPassInfo.pSubpasses = &subpass;
	renderPassInfo.dependencyCount = 1;
	renderPassInfo.pDependencies = &dependency;


	VkRenderPass renderPass;
	auto err = vkCreateRenderPass(设备, &renderPassInfo, nullptr, &renderPass);
	assert(err == VK_SUCCESS);

	return renderPass;
}




VkRenderPass f_fb_创建合成渲染通道(VkDevice& dev, const VkFormat& 颜色格式, const VkFormat& 深度格式, E_MS次数 采样次数) {
	VkAttachmentDescription attachmentDescriptions[3] = {};

	attachmentDescriptions[0].format = 颜色格式;						// MSAA 颜色格式
	attachmentDescriptions[0].samples = f_get多重采样Bits(采样次数);
	attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;				// Resolve后不需要存储
	attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	attachmentDescriptions[2].format = 颜色格式; // 非MSAA 颜色格式
	attachmentDescriptions[2].samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentDescriptions[2].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescriptions[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentDescriptions[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescriptions[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[2].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[2].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	
	// 深度/模板附件
	attachmentDescriptions[1].format = 深度格式;
	attachmentDescriptions[1].samples = f_get多重采样Bits(采样次数);									// 深度/模板通常不使用MSAA
	attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;


	// MSAA 颜色附件引用（索引0）
	VkAttachmentReference colorAttachment[1] = {
		{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
	};

	// 第一个非 MSAA 颜色附件引用（索引1），用于 Resolve 操作
	VkAttachmentReference resolveAttachment[1] = {
		{2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
	};
	

	// 深度/模板附件引用（如果有的话）
	VkAttachmentReference depthStencilAttachmentRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };

	

	VkSubpassDescription subpassDescription = {};
	subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	subpassDescription.flags = 0;
	subpassDescription.inputAttachmentCount = 0;
	subpassDescription.pInputAttachments = nullptr;
	subpassDescription.colorAttachmentCount = 1;
	subpassDescription.pColorAttachments = colorAttachment;
	subpassDescription.pResolveAttachments = resolveAttachment;				// 指向Resolve目标
	subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentRef;
	subpassDescription.preserveAttachmentCount = 0;
	subpassDescription.pPreserveAttachments = nullptr;


	// 渲染通道创建信息
	VkRenderPassCreateInfo renderPassInfo = {};
	renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	renderPassInfo.attachmentCount = 3;
	renderPassInfo.pAttachments = attachmentDescriptions;
	renderPassInfo.subpassCount = 1;
	renderPassInfo.pSubpasses = &subpassDescription;


	VkRenderPass 渲染通道;
	VkResult res = vkCreateRenderPass(dev, &renderPassInfo, NULL, &渲染通道);
	if (res != VK_SUCCESS) {
		throw std::runtime_error("创建渲染过程失败");
	}

	return 渲染通道;

}

VkRenderPass f_fb_创建几何缓存渲染通道(VkDevice& dev, const VkFormat& 颜色格式, const VkFormat& 深度格式, E_MS次数 采样次数) {
	VkAttachmentDescription attachmentDescriptions[3] = {};

	attachmentDescriptions[0].format = 颜色格式;						// MSAA 颜色格式
	attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;				// Resolve后不需要存储
	attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	attachmentDescriptions[1].format = 颜色格式; // 非MSAA 颜色格式
	attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	// 深度/模板附件
	attachmentDescriptions[2].format = 深度格式;
	attachmentDescriptions[2].samples = VK_SAMPLE_COUNT_1_BIT;									// 深度/模板通常不使用MSAA
	attachmentDescriptions[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentDescriptions[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentDescriptions[2].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
	attachmentDescriptions[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;



	// MSAA 颜色附件引用（索引0）
	VkAttachmentReference colorAttachment[2] = {
		{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
		{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
	};

	// 深度/模板附件引用（如果有的话）
	VkAttachmentReference depthStencilAttachmentRef = { 2, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };



	VkSubpassDescription subpassDescription = {};
	subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	subpassDescription.flags = 0;
	subpassDescription.inputAttachmentCount = 0;
	subpassDescription.pInputAttachments = nullptr;
	subpassDescription.colorAttachmentCount = 2;
	subpassDescription.pColorAttachments = colorAttachment;
	subpassDescription.pResolveAttachments = nullptr;				// 指向Resolve目标
	subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentRef;
	subpassDescription.preserveAttachmentCount = 0;
	subpassDescription.pPreserveAttachments = nullptr;

	//VkSubpassDescription subpassDescriptionGBuffer = {};
	//subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	//subpassDescription.flags = 0;
	//subpassDescription.inputAttachmentCount = 0;
	//subpassDescription.pInputAttachments = nullptr;
	//subpassDescription.colorAttachmentCount = 2;
	//subpassDescription.pColorAttachments = gbuffer_colorAttachment;
	//subpassDescription.pResolveAttachments = nullptr;				// 指向Resolve目标
	//subpassDescription.pDepthStencilAttachment = &depthStencilAttachmentRef;
	//subpassDescription.preserveAttachmentCount = 0;
	//subpassDescription.pPreserveAttachments = nullptr;

	// 子通道数组
	//VkSubpassDescription subpasses[2] = {subpassDescription, subpassDescriptionGBuffer};


	// 渲染通道创建信息
	VkRenderPassCreateInfo renderPassInfo = {};
	renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	renderPassInfo.attachmentCount = 3;
	renderPassInfo.pAttachments = attachmentDescriptions;
	renderPassInfo.subpassCount = 1;
	renderPassInfo.pSubpasses = &subpassDescription;



	VkRenderPass 渲染通道;
	VkResult res = vkCreateRenderPass(dev, &renderPassInfo, NULL, &渲染通道);
	if (res != VK_SUCCESS) {
		throw std::runtime_error("创建渲染过程失败");
	}

	return 渲染通道;
}

VkRenderPass f_fb_创建渲染通道(VkDevice& dev, const VkFormat& 颜色格式, bool 窗口呈现) {
	VkAttachmentDescription attachmentColor = {};
	attachmentColor.format = 颜色格式;
	attachmentColor.samples = VK_SAMPLE_COUNT_1_BIT;
	attachmentColor.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
	attachmentColor.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
	attachmentColor.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
	attachmentColor.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
	attachmentColor.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

	if (窗口呈现) {
		attachmentColor.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
	}
	else {
		attachmentColor.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	}
	

	VkAttachmentReference colorAttachmentRef = {};
	colorAttachmentRef.attachment = 0;
	colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;


	VkSubpassDescription subpass = {};
	subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	subpass.colorAttachmentCount = 1;
	subpass.pColorAttachments = &colorAttachmentRef;


	VkSubpassDependency dependency = {};
	dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
	dependency.dstSubpass = 0;
	dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
	dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
	dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
	dependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;



	VkAttachmentDescription Attachment[1] = { attachmentColor };

	VkRenderPassCreateInfo renderPassInfo = {};
	renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	renderPassInfo.attachmentCount = 1;
	renderPassInfo.pAttachments = Attachment;
	renderPassInfo.subpassCount = 1;
	renderPassInfo.pSubpasses = &subpass;
	renderPassInfo.dependencyCount = 1;
	renderPassInfo.pDependencies = &dependency;


	VkRenderPass renderPass;
	auto err = vkCreateRenderPass(dev, &renderPassInfo, nullptr, &renderPass);
	assert(err == VK_SUCCESS);

	return renderPass;
}

VkRenderPass f_fb_创建交换链渲染通道(VkDevice& dev, const VkFormat& 颜色格式, const VkFormat& 深度格式, E_MS次数 采样次数) {
	VkAttachmentDescription 附件描述[4] = {};

	VkSubpassDescription 子通道 = {};
	VkRenderPassCreateInfo rpInfo = {};
	VkSubpassDependency 子通道依赖[2] = {};

	VkAttachmentReference 颜色附件引用[2] = {};
	VkAttachmentReference 深度附件引用[2] = {};
	VkAttachmentReference 解析附件引用 = {};

	子通道.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
	子通道.flags = 0;

	rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
	rpInfo.pNext = NULL;


	if (采样次数 != E_MS次数::e_MS_1) {
		附件描述[0].format = 颜色格式; //设置用于多重采样的颜色附件格式
		附件描述[0].samples = f_get多重采样Bits(采样次数); //设置多重采样数
		附件描述[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;//渲染通道开始时颜色附件的操作
		附件描述[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;//渲染通道结束时颜色附件的操作
		附件描述[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; //颜色附件的最终布局
		附件描述[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
		附件描述[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		附件描述[0].flags = 0;

		附件描述[1].format = 颜色格式; //设置解析附件的格式(服务于呈现)
		附件描述[1].samples = VK_SAMPLE_COUNT_1_BIT; //设置多重采样数
		附件描述[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;//渲染通道开始时解析附件的操作
		附件描述[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; //渲染通道结束时解析附件的操作
		附件描述[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; //解析附件的最终布局
		附件描述[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
		附件描述[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		附件描述[1].flags = 0;

		附件描述[2].format = 深度格式; //设置用于多重采样的深度附件格式
		附件描述[2].samples = f_get多重采样Bits(采样次数); //设置多重采样数
		附件描述[2].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; //用于多重采样的深度附件的最终布局
		附件描述[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
		附件描述[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
		附件描述[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		附件描述[2].flags = 0;



		解析附件引用.attachment = 1;
		解析附件引用.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

		颜色附件引用[0].attachment = 0;
		颜色附件引用[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
		
		深度附件引用[0].attachment = 2;
		深度附件引用[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;


		子通道.colorAttachmentCount = 1;
		子通道.pColorAttachments = 颜色附件引用;
		子通道.pDepthStencilAttachment = 深度附件引用;

		子通道.pResolveAttachments = &解析附件引用;
		子通道.preserveAttachmentCount = 0;
		子通道.pPreserveAttachments = NULL;



		子通道依赖[0].srcSubpass = VK_SUBPASS_EXTERNAL;
		子通道依赖[0].dstSubpass = 0;
		子通道依赖[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
		子通道依赖[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
		子通道依赖[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
		子通道依赖[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
		子通道依赖[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

		子通道依赖[1].srcSubpass = 0;
		子通道依赖[1].dstStageMask = 0;
		子通道依赖[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		子通道依赖[1].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		子通道依赖[1].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
		子通道依赖[1].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
		子通道依赖[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

		rpInfo.attachmentCount = 3;
		rpInfo.dependencyCount = 2;
	}
	else {
		// 颜色附件描述
		附件描述[0].format = 颜色格式; // 设置颜色附件格式
		附件描述[0].samples = VK_SAMPLE_COUNT_1_BIT; // 无多重采样
		附件描述[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // 渲染通道开始时颜色附件的操作
		附件描述[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // 渲染通道结束时颜色附件的操作
		附件描述[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
		附件描述[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		附件描述[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; // 颜色附件的最终布局
		附件描述[0].flags = 0;

		// 深度附件描述
		附件描述[1].format = 深度格式; // 设置深度附件格式
		附件描述[1].samples = VK_SAMPLE_COUNT_1_BIT; // 无多重采样
		附件描述[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; // 深度附件的最终布局
		附件描述[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // 渲染通道开始时深度附件的操作
		附件描述[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // 渲染通道结束时深度附件的操作
		附件描述[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
		附件描述[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
		附件描述[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		附件描述[1].flags = 0;




		// 颜色附件引用
		颜色附件引用[0].attachment = 0;
		颜色附件引用[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

		// 深度附件引用
		深度附件引用[0].attachment = 1;
		深度附件引用[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

		// 子通道描述
		子通道.colorAttachmentCount = 1;
		子通道.pColorAttachments = 颜色附件引用;
		子通道.pDepthStencilAttachment = 深度附件引用;


		// 子通道依赖
		子通道依赖[0].srcSubpass = VK_SUBPASS_EXTERNAL;
		子通道依赖[0].dstSubpass = 0;
		子通道依赖[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		子通道依赖[0].srcAccessMask = 0;
		子通道依赖[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		子通道依赖[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
		//子通道依赖[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

		//子通道依赖[1].srcSubpass = 0;
		//子通道依赖[1].dstSubpass = VK_SUBPASS_EXTERNAL;
		//子通道依赖[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		//子通道依赖[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
		//子通道依赖[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
		//子通道依赖[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
		//子通道依赖[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
		// 渲染通道创建信息
		rpInfo.attachmentCount = 2;
		rpInfo.dependencyCount = 1;
	}
	

	rpInfo.pAttachments = 附件描述;
	rpInfo.subpassCount = 1;
	rpInfo.pSubpasses = &子通道;
	rpInfo.pDependencies = 子通道依赖;



	VkRenderPass 渲染通道;
	VkResult res = vkCreateRenderPass(dev, &rpInfo, NULL, &渲染通道);
	if (res != VK_SUCCESS) {
		throw std::runtime_error("创建渲染过程失败");
	}
	return 渲染通道;
}




